//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.IO;
using System.Security;
using System.Text.RegularExpressions;
using CommunityServer.Components;
using CommunityServer.ControlPanel.UI;
using CommunityServer.Controls;
using CommunityServer.ControlPanel.Controls;
using CommunityServer.Galleries.Components;
using CA = ComponentArt.Web.UI;
using ResourceControl = CommunityServer.ControlPanel.Controls.ResourceControl;

namespace CommunityServer.ControlPanel.PhotoAdmin
{
	/// <summary>
	///		Summary description for GroupTreeViewControl.
	/// </summary>
	public class GroupTreeViewControl : BaseGalleryAdminControl
	{

		protected string AjaxQueryStringKey
		{
			get
			{
				return "___" + this.ClientID;
			}
		}

		#region Child Controls

		protected ContextMenu GroupContextMenu;
		protected ContextMenu SectionContextMenu;
		protected CA.TreeView Tree;
		//ArrayList sectionTree = new ArrayList();

		#endregion
		private string addGroupButtonClientID;
		public string AddGroupButtonClientID
		{
			get{return addGroupButtonClientID;}
			set{addGroupButtonClientID = value;}
		}

		private string addSectionButtonClientID;
		public string AddSectionButtonClientID
		{
			get{return addSectionButtonClientID;}
			set{addSectionButtonClientID = value;}
		}

		private string deleteButtonClientID;
		public string DeleteButtonClientID
		{
			get{return deleteButtonClientID;}
			set{deleteButtonClientID = value;}
		}
		
		protected string AjaxQueryStringValue = "{0}:{1}";
		protected string AjaxQueryStringValuePattern = "(\\d+):([\\w\\.-]*)";
		private bool IsAdministrator = false;
		protected ResourceControl Resourcecontrol1;
		private bool IsEdit = false;

		private void Page_Load(object sender, System.EventArgs e)
		{
			if (this.Page.Request.QueryString[AjaxQueryStringKey] != null)
				HandleXmlRequest(this.Page.Request.QueryString[AjaxQueryStringKey]);

			AjaxManager.Register(this,"GroupTreeViewControl");

			IsAdministrator = CSContext.Current.User.IsGalleryAdministrator;

			if(!Page.IsPostBack)
			{
				EnsureChildControls();
				BuildGroupTree();
			}
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		///		Required method for Designer support - do not modify
		///		the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion
		
		//private void AddSectionToTree(int sectionID)
		//{
		//	//this.sectionTree.Add(sectionID);
		//	Gallery section = CommunityServer.Galleries.Galleries.GetGallery(sectionID, false); 
		//	if (section.ParentID > 0)
		//		AddSectionToTree(section.ParentID);
		//}


		private CA.TreeViewNode BuildNode(string name)
		{
			CA.TreeViewNode node = new CA.TreeViewNode();

			if (name.Length > 30)
				node.Text = name.Substring(0, 27) + "...";
			else
				node.Text = name;

			return node;
		}


		private CA.TreeViewNode BuildRootnode()
		{
			CA.TreeViewNode node = new CA.TreeViewNode();
			node.Text = "Groups";
			node.DraggingEnabled = false;
			node.DroppingEnabled = true;
			node.EditingEnabled = false;
			node.ImageUrl = "folders.gif";
			node.Value = "-1:-1";
			node.Expanded = true;
			node.ID = "RootNode";
			return node;
		}


		private void BuildGroupTree()
		{
			if (Tree == null)
				return;

			// Get all forum groups
			//ArrayList forumGroups = ForumGroups.GetForumGroups(false, isAdmin);
			ArrayList groups = GalleryGroups.GetGroups(false, false, IsEdit); 

			// Create root node
			CA.TreeViewNode rootNode = BuildRootnode();
			Tree.Nodes.Add(rootNode);
			
			CA.TreeViewNode node;
			foreach (CommunityServer.Components.Group group in groups)
			{
				// Get a list of sections in this group

				node = BuildNode(group.Name);

				node.ImageUrl = "folders.gif";
				node.DraggingEnabled = true;
				node.DroppingEnabled = true;
				node.EditingEnabled = true;
				node.ID = String.Format("{0}:-1", group.GroupID);
				node.Value = String.Format("{0}:-1", group.GroupID);

				if (group.HasSections)
					node.Text += "(" + group.Sections.Count.ToString() + ")";

				rootNode.Nodes.Add(node);

				CSContext cntx = CSContext.Current;
				if (group.GroupID == cntx.GroupID)
				{
					node.Expanded = true;
					if (cntx.SectionID < 0)
					{
						node.CssClass = Tree.SelectedNodeCssClass;
						node.HoverCssClass = Tree.SelectedNodeCssClass;
					}

				}

				BuildSectionTree(group.GroupID, -1, node.Nodes);
			}
		}


		private void BuildSectionTree(int groupID, int sectionID, CA.TreeViewNodeCollection nodes)
		{
			ArrayList groups;

			if (sectionID > 0)
				//forums = CommunityServer.Discussions.Components.Forums.GetForum(sectionID, !isAdmin, isAdmin).Sections;
				groups = CommunityServer.Galleries.Galleries.GetGallery(sectionID, false).Sections; 
			else
				//forums = CommunityServer.Discussions.Components.Forums.GetForumsByForumGroupID(groupID,!isAdmin,isAdmin,false,false);
				groups = CommunityServer.Galleries.Galleries.GetGalleriesByGroupID(groupID, IsAdministrator, false, IsEdit); 

			CA.TreeViewNode node;
			foreach (Section section in groups)
			{
				node = BuildNode(section.Name);
				node.Target = "sectionEditFrame";
				node.EditingEnabled = false;
				node.DraggingEnabled = true;
				node.DroppingEnabled = true;
				node.Checked = section.IsActive;
				if(section.IsActive)
					node.ImageUrl = "notes.gif"; 
				else
					node.ImageUrl = "notesdisabled.gif"; 

				node.ID = String.Format("{0}:{1}", section.GroupID, section.SectionID);
				node.Value = String.Format("{0}:{1}", section.GroupID, section.SectionID);

				nodes.Add(node);

				if (section.SectionID == CSContext.Current.SectionID)
				{
					node.CssClass = Tree.SelectedNodeCssClass;
					node.HoverCssClass = Tree.SelectedNodeCssClass;
				}
			}
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string ChangeSectionEnabled(int groupID, int sectionID)
		{
			if( !IsAdministrator ) 
				return "-1";

			if(sectionID > 0)
			{
				Gallery g = CommunityServer.Galleries.Galleries.GetGallery(sectionID, false); 
				g.IsActive = !g.IsActive;
				CommunityServer.Galleries.Galleries.Update(g); 
			}

			return string.Format("{0}^{1}",groupID, sectionID ) ;
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string GetNextName(int groupID)
		{
			string name =  CommunityServer.ControlPanel.Components.ResourceManager.GetString("CP_Photos_NewGallery");
			
			ArrayList galleries = CommunityServer.Galleries.Galleries.GetGalleries(CSContext.Current.User.UserID, true, true, true); 
			name =  Sections.NextSectionName(galleries, name); 

			return string.Format("{0}^{1}",groupID, name ) ;
		}

		protected void HandleXmlRequest(string value)
		{
			Match m = Regex.Match(value, AjaxQueryStringValuePattern);
			if (m != null)
			{
				CSContext cntx = CSContext.Current;
				cntx.GroupID = int.Parse(m.Groups[1].Value);
				cntx.SectionID = int.Parse(m.Groups[2].Value);

				CA.TreeView tree = new CA.TreeView();

				BuildSectionTree(cntx.GroupID, cntx.SectionID, tree.Nodes);

				Page.Response.Clear();
				Page.Response.ContentType = "text/xml";
				Page.Response.Write(tree.GetXml());
				Page.Response.End();
			}
		}

	
		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public void ReorderForumOrGroup(int groupID, int sectionID, int index)
		{
			if (sectionID < 0)
			{
				// ReOrder Group
				Groups.ReOrder(groupID, index);
			}
			else
			{
				// ReOrder Section
				Sections.MoveOrReOrder(groupID, sectionID, index);
			}
		}


		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string MoveSection(int groupID, int sectionID, int targetGroupID, int targetSectionID)
		{
			//Forum forum = CommunityServer.Discussions.Components.Forums.GetForum(sectionID, false, true );
			IsEdit = true;
			Gallery section = CommunityServer.Galleries.Galleries.GetGallery(sectionID, false); 

			// Determine if the user moved the Forum to another group and/or parent forum...
			//	or if this move was just a change in sort order in the same group & parent forum
			if (section.GroupID == targetGroupID)
			{
				if (targetSectionID < 0 || section.ParentID == targetSectionID)
				{
					// This is just a change in sort order. We can't do anything until we know
					//	the new index that the node was dropped in. So let client-side function know this...
					return "-1";
				}
			}
			else
			{
				// Move the forum
				section.GroupID = targetGroupID;

				if (targetSectionID < 0)
					section.ParentID = 0;
				else
					section.ParentID = targetSectionID;

				// Move any children sections as well
				if (section.Sections.Count > 0)
				{
					foreach (Gallery g in section.Sections)
					{
						MoveSubSection(g, targetGroupID);
					}
				}

				CommunityServer.Galleries.Galleries.Update(section);

			}

			return string.Format("{0}^{1}^{2}^{3}",groupID, targetGroupID, sectionID, targetSectionID) ;
		}

		protected void MoveSubSection(Gallery section, int groupID)
		{
			section.GroupID = groupID;
			CommunityServer.Galleries.Galleries.Update(section);

			// Move any children sections as well
			if (section.Sections.Count > 0)
			{
				foreach (Gallery s in section.Sections)
				{
					MoveSubSection(s, groupID);
				}
			}
		}


	
		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public int RenameGroup(int groupID, string newName)
		{
			CommunityServer.Components.Group group = GalleryGroups.GetGroup(groupID, false, true, true) ;
			group.Name = newName.Trim();

			// Check to make sure the same name doesn't already exist
			foreach(CommunityServer.Components.Group g in GalleryGroups.GetGroups(false, true, true))
			{
				if((g.Name == group.Name) && (g.GroupID != group.GroupID))
					return -1;
			}

			Groups.UpdateGroup(group);

			return groupID;
		}


		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string AddGroup()
		{

			string name =  CommunityServer.ControlPanel.Components.ResourceManager.GetString("CP_GroupManager_NewGroup");
			ArrayList groups = GalleryGroups.GetGroups(true, true, true); 
			name = Groups.NextGroupName(groups, name); 

			CommunityServer.Components.Group group = new CommunityServer.Components.Group();
			group.ApplicationType = ApplicationType.Gallery;
			group.Name = name.Trim();
			
			int groupID = Groups.AddGroup(group);
	
			//Not Cluster safe, but lets try and update the cache
			groups = GalleryGroups.GetGroups(true, true, true); 

			return string.Format("{0}^{1}",groupID, name ) ;
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public int DeleteGroup(int groupID)
		{
			if( !IsAdministrator ) 
				return 0;

			CommunityServer.Components.Group group = GalleryGroups.GetGroup(groupID, false, true, true);

			// Don't delete a group if it has sections
			if(GalleryGroups.HasChildSections(group.GroupID))
				return 0;

			Groups.DeleteGroup(group);
			return groupID;
		}	

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string AddSection(int groupID, string name)
		{
			if(name.Trim() == string.Empty)
				return "-1";

			//string name =  CommunityServer.ControlPanel.Components.ResourceManager.GetString("CP_Photos_NewGallery");

			CSContext cntx = CSContext.Current;
			ArrayList galleries = CommunityServer.Galleries.Galleries.GetGalleries(cntx.User.UserID, true, true, true); 
			//name =  Sections.NextSectionName(galleries, name); 
			if(Sections.HasSection(galleries, name))
				return "0";

			Gallery g = new Gallery() ;
			
			string formattedKey = null;
			Globals.ValidateApplicationKey(name, out formattedKey);
			
			//Set remaining gallery settings
			g.GroupID = groupID;
			g.Name = name;
			g.ApplicationKey = formattedKey;
			g.IsActive = false;
			g.SettingsID = cntx.SiteSettings.SettingsID;
			g.ApplicationType = ApplicationType.Gallery;

			g.IsSearchable =  true;

			//Create The Gallery
			g.SectionID = CommunityServer.Galleries.Galleries.AddGallery(g);

			//Create the Folder on the webserver
			try
			{
				if(GalleryConfiguration.Instance().CreateGalleryDirectories)
					WebDirectory.Create(Globals.GetSiteUrls().Locations["galleries"] + g.ApplicationKey);
			}
			catch(IOException e)
			{ new CSException(CSExceptionType.AccessDenied, "CreateGallery: Permission to add the folder on filesystem denied.", e).Log(); }
			catch(SecurityException e)
			{ new CSException(CSExceptionType.AccessDenied, "CreateGallery: Permission to add the folder on filesystem denied.", e).Log(); }
			catch { }
			
			//Not Cluster safe, but lets try and update the cache
			galleries = CommunityServer.Galleries.Galleries.GetGalleries(cntx.User.UserID, true, true, true); 
			
			return string.Format("{0}^{1}^{2}",groupID, g.SectionID, name) ;
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string DeleteSection(int groupID, int sectionID)
		{
			if( !IsAdministrator ) 
				return "0";

			CommunityServer.Galleries.Galleries.DeleteGallery(sectionID);
			return string.Format("{0}^{1}",groupID, sectionID) ;
		}	


	}
}
